#include "BlockQueue.hpp"
#include "Task.hpp"
#include <ctime>

void *Cosumer(void *args)
{
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);

    while (true)
    {
        // 把任务拿出来消费
        Task t = bq->pop();

        // 计算
        // t.run();
        t();

        std::cout << "处理任务: " << t.GetTask() << " 运算结果是: " << t.GetResult() <<"thread id: "<<pthread_self()<< std::endl;
    }
}

void *Producer(void *args)
{
    int len = opers.size();
    BlockQueue<Task> *bq = static_cast<BlockQueue<Task> *>(args);
    int x = 10;
    int y = 20;

    while (true)
    {
        // 模拟生产者生产数据
        int data1 = rand() % 10 + 1; //[1,10]
        usleep(10);
        int data2 = rand() % 10 + 1;
        char op = opers[rand() % len];
        Task t(data1, data2, op);

        // 生产
        bq->push(t);
        std::cout << "生产了一个任务：" << t.GetTask() <<"thread id :"<<pthread_self()<< std::endl;
        sleep(2);
    }
}

// 多生产，多消费
int main()
{
    srand(time(nullptr));
    // BlockQueue内部不仅可以传递int这样的整数，还可以传递对象或者任务
    BlockQueue<Task> *bq = new BlockQueue<Task>();
    pthread_t c[3], p[5];
    for (int i = 0; i < 3; ++i)
    {
        pthread_create(c + i, nullptr, Cosumer, bq);  //数组名是首元素地址
    }

    for (int i = 0; i < 5; ++i)
    {
        pthread_create(p + i, nullptr, Producer, bq);
    }

    for (int i = 0; i < 3; i++)
    {
        pthread_join(c[i], nullptr);
    }

    for (int i = 0; i < 5; i++)
    {
        pthread_join(p[i], nullptr);
    }

    delete bq;
    return 0;
}

// 单生产，单消费
//  int main()
//  {
//      srand(time(nullptr));
//      //BlockQueue内部不仅可以传递int这样的整数，还可以传递对象或者任务
//      BlockQueue<Task>* bq=new BlockQueue<Task>();
//      pthread_t c,p;
//      pthread_create(&c,nullptr,Cosumer,bq);       //传入的bq让生产与消费者建立了联系
//      pthread_create(&p,nullptr,Producer,bq);

//     pthread_join(c,nullptr);
//     pthread_join(p,nullptr);
//     delete bq;
//     return 0;
// }